package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.Category;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.CategoryMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper,Category> implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private QuestionMapper questionMapper;

    @Override
    public List<Category> getAllCategories() {
        List<Category> categories = baseMapper.selectList(new LambdaQueryWrapper<Category>().orderByAsc(Category::getSort));
        addCategoryQuestionCount(categories);
        return categories;
    }
    private void addCategoryQuestionCount(List<Category> categories) {
        List<Map<Long, Long>> categoryQuestionCount = questionMapper.getCategoryQuestionCount();
        Map<Long, Long> countMap = categoryQuestionCount.stream().collect(Collectors.toMap(
                map -> map.get("category_id"),
                map -> map.get("count")
        ));
        categories.forEach(category -> category.setCount(countMap.getOrDefault(category.getId(),0L)));
    }
        @Override
    public List<Category> getTreeList() {
        List<Category> categories = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
                .orderByAsc(Category::getSort));
        addCategoryQuestionCount(categories);
        Map<Long, List<Category>> categoryMap = categories.stream().collect(Collectors.groupingBy(Category::getParentId));
        categories.forEach(category -> {
                List<Category> childCategory = categoryMap.getOrDefault(category.getId(), new ArrayList<>());
                category.setChildren(childCategory);
                category.setCount(childCategory.stream().mapToLong(Category::getCount).sum() + category.getCount());
        });
        return categories.stream().filter(category -> category.getParentId() == 0).collect(Collectors.toList());

    }

    @Override
    public void addCategory(Category category) {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getName, category.getName()).eq(Category::getParentId, category.getParentId());
        if (baseMapper.selectOne(queryWrapper) != null) {
            Category parentCategory = baseMapper.selectOne(new LambdaQueryWrapper<Category>().eq(Category::getId, category.getParentId()));
            throw new ExamException(250, "该父分类<" + parentCategory.getName() + ">下已存在"+category.getName()+"分类");
        }
        baseMapper.insert(category);
    }

    @Override
    public void updateCategory(Category category) {
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Category>()
                .eq(Category::getName, category.getName())
                .eq(Category::getParentId, category.getParentId())
                .ne(Category::getId, category.getId()));
        if (exists) {
            throw new ExamException(500, "该父分类下已存在"+category.getName()+"分类");
        }
        baseMapper.updateById(category);
    }

    @Override
    public void deleteCategory(Long id) {
        Long count = baseMapper.selectCount(new LambdaQueryWrapper<Category>().eq(Category::getParentId, id));
        if (count > 0) {
            throw new ExamException(750, "该分类下还有子分类，不能删除");
        }
        Long count1 = questionMapper.selectCount(new LambdaQueryWrapper<Question>().eq(Question::getCategoryId, id));
        if (count1 > 0) {
            throw new ExamException(1000, "该分类下还有题目，不能删除");
        }
        baseMapper.deleteById(id);
    }

}